//! \file       ArcCMB.cs
//! \date       2019 Mar 21
//! \brief      PineSoft resource archive.
//
// Copyright (C) 2019 by morkt
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using GameRes.Compression;

namespace GameRes.Formats.PineSoft
{
    [Export(typeof(ArchiveFormat))]
    public class CmbOpener : ArchiveFormat
    {
        public override string         Tag { get { return "CMB"; } }
        public override string Description { get { return "PineSoft resource archive"; } }
        public override uint     Signature { get { return 0; } }
        public override bool  IsHierarchic { get { return false; } }
        public override bool      CanWrite { get { return false; } }

        public override ArcFile TryOpen (ArcView file)
        {
            if (!file.Name.HasExtension (".cmb"))
                return null;
            var arc_name = Path.GetFileNameWithoutExtension (file.Name);
            int arc_num = Int32.Parse (arc_name);
            var scheme = QueryScheme (file.Name);
            if (scheme.Length <= arc_num)
                return null;
            var offsets = scheme[arc_num];
            uint last_offset = offsets[offsets.Length-1];
            if (last_offset != file.MaxOffset)
                return null;
            int count = offsets.Length - 1;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                if (offsets[i] == uint.MaxValue)
                    continue;
                var entry = new PackedEntry {
                    Name = i.ToString ("D5"),
                    Offset = offsets[i],
                };
                dir.Add (entry);
            }
            for (int i = 1; i < dir.Count; ++i)
            {
                var entry = dir[i-1];
                entry.Size = (uint)(dir[i].Offset - entry.Offset);
            }
            dir[dir.Count-1].Size = (uint)(last_offset - dir[dir.Count-1].Offset);
            DetectFileTypes (file, dir);
            return new ArcFile (file, this, dir);
        }

        public override Stream OpenEntry (ArcFile arc, Entry entry)
        {
            var input = arc.File.CreateStream (entry.Offset, entry.Size);
            var pent = entry as PackedEntry;
            if (null == pent || !pent.IsPacked)
                return input;
            return new LzssStream (input);
        }

        void DetectFileTypes (ArcView file, List<Entry> dir)
        {
            foreach (PackedEntry entry in dir)
            {
                uint signature = file.View.ReadUInt32 (entry.Offset);
                if (0x5367674F == signature)
                {
                    entry.ChangeType (OggAudio.Instance);
                    continue;
                }
                uint id2 = file.View.ReadUInt32 (entry.Offset+4);
                if (0x4450420F == (id2 & 0xFFFFFF0F))
                {
                    entry.ChangeType (s_BpdFormat.Value);
                    entry.IsPacked = true;
                    entry.UnpackedSize = signature;
                    entry.Offset += 4;
                    entry.Size -= 4;
                    continue;
                }
                else if (entry.Size == signature + 0x18 && 0x10 == id2)
                {
                    entry.Type = "audio";
                    continue;
                }
                else if (entry.Size <= 0x2C)
                {
                    continue;
                }
                int count = file.View.ReadInt32 (entry.Offset+0x24);
                if ((count + 1) * 4 + 0x28 == signature)
                {
                    entry.Type = "archive";
                }
            }
        }

        uint[][] QueryScheme (string arc_name)
        {
            return DefaultLayout;
        }

        static readonly ResourceInstance<ImageFormat> s_BpdFormat = new ResourceInstance<ImageFormat> ("BPD");

        // [051125][PineSoft] Close-up!
        static uint[][] DefaultLayout = new uint[][] {
            new uint[] {
                0x00000000, 0x00070EC3, 0x000DDD4A, 0x0014D337, 0x001BC99B, 0x00229F1E, 0xFFFFFFFF, 0x00297C1C,
                0x002F332A, 0x0034F349, 0xFFFFFFFF, 0x003AA985, 0xFFFFFFFF, 0xFFFFFFFF, 0x004067F4, 0x00471DF5,
                0x004DBC48, 0x00546139, 0x005B05F0, 0x0061ADD6, 0xFFFFFFFF, 0x00684D46, 0x006D67E6, 0x0072860F,
                0x00779FFE, 0x007CBDEE, 0x0081E283, 0xFFFFFFFF, 0x0087120B, 0x008D88A3, 0xFFFFFFFF, 0xFFFFFFFF,
                0x009419E8, 0x009A9A40, 0xFFFFFFFF, 0x00A13D97, 0x00A6DA31, 0x00AC86CA, 0x00B222E9, 0x00B7C86E,
                0x00BD71D6, 0xFFFFFFFF, 0x00C3283C, 0x00C91F73, 0x00CF0EBE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00D50333,
                0xFFFFFFFF, 0x00DAF806, 0x00E02761, 0xFFFFFFFF, 0xFFFFFFFF, 0x00E5522D, 0xFFFFFFFF, 0xFFFFFFFF,
                0x00EA84BC, 0x00EE1B50, 0x00F1DF50, 0x00F5B2C3, 0x00F97CFF, 0x00FD4A84, 0x0100E1DB, 0x010476C9,
                0x010812E4, 0x010BC57C, 0xFFFFFFFF, 0x010F92E6, 0xFFFFFFFF, 0xFFFFFFFF, 0x01134FA3, 0x0116891D,
                0x0119DFD6, 0x011D524C, 0x0120C267, 0x0124346F, 0x0127702C, 0x012AA56F, 0xFFFFFFFF, 0x012EFBE0,
                0x01335317, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0137A85C, 0x013B7717, 0xFFFFFFFF, 0xFFFFFFFF,
                0x013F4ACE, 0xFFFFFFFF, 0xFFFFFFFF, 0x0142F507, 0x014843D9, 0x014D748E, 0x0152B936, 0x01580847,
                0x015D3F6A, 0xFFFFFFFF, 0x0162A82A, 0x01673943, 0x016BCBD7, 0x01703F1D, 0x0174B23F, 0x01792C1C,
                0xFFFFFFFF, 0x017DBD52, 0x0182FD40, 0x01882690, 0x018D6E9C, 0x0192AE5E, 0x0197DD5C, 0xFFFFFFFF,
                0x019D2508, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x01A2B507, 0xFFFFFFFF, 0xFFFFFFFF, 0x01A84625,
                0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x01AD7BD1, 0xFFFFFFFF, 0xFFFFFFFF, 0x01B2B328, 0x01B7E7EF,
                0xFFFFFFFF, 0x01BD1E54, 0x01C2532C, 0xFFFFFFFF, 0xFFFFFFFF, 0x01C788DD, 0xFFFFFFFF, 0xFFFFFFFF,
                0x01CC3547, 0x01D0D219, 0xFFFFFFFF, 0xFFFFFFFF, 0x01D559B0, 0x01D9FD46, 0x01DE6686, 0x01E2FBEF,
                0x01E78DB0, 0x01EC3212, 0xFFFFFFFF, 0x01F0D643, 0x01F4EDF1, 0x01F9344F, 0xFFFFFFFF, 0x01FD7741,
                0xFFFFFFFF, 0xFFFFFFFF, 0x0201AD19, 0x0205E17F, 0x020A02BF, 0x020E29DD, 0x021251BA, 0x021688B9,
                0x021ABE9A, 0x021EED6C, 0x0222A1D6, 0x02264D43, 0x022A2231, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
                0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x022DC602,
                0x02331A5B, 0x02384FF4, 0x023DBE1A, 0x0242F0D5, 0x02484702, 0xFFFFFFFF, 0x024D7AAB, 0x02518DEC,
                0x02554B59, 0x02597DCF, 0x025D906C, 0x02615353, 0x02651BAB, 0x02692EE5, 0x026C8F46, 0x026FE76B,
                0x02735CC3, 0x0276BCCE, 0x027A1B3D, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
                0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x027D9190, 0x02828915, 0x02877561, 0x028CA24D, 0x02919945,
                0x02968C2B, 0xFFFFFFFF, 0x029B6B18, 0x029EB7DE, 0xFFFFFFFF, 0x02A2003D, 0x02A54CD9, 0x02A89AE9,
                0x02ABE8A1, 0x02AF3612, 0x02B3E0A8, 0x02B877F6, 0x02BD4308, 0x02C1B421, 0x02C64D52, 0xFFFFFFFF,
                0x02CAF92F, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x02CF5E81,
                0x02D3E2F3, 0x02D84B3F, 0x02DCDD34, 0x02E13150, 0x02E59CC7, 0xFFFFFFFF, 0x02E9F4C4, 0x02EE795D,
                0xFFFFFFFF, 0x02F2FAE0, 0x02F785BA, 0x02FC1907, 0xFFFFFFFF, 0x0300A5A7, 0x0306E9E0, 0xFFFFFFFF,
                0x030D2C52, 0xFFFFFFFF, 0xFFFFFFFF, 0x03137115, 0x03175D30, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
                0xFFFFFFFF, 0x031B471C, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0321E093,
                0x0326A01A, 0x032B614D, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0330220D, 0x0334B269, 0x033941F8,
                0x033DD216, 0xFFFFFFFF, 0xFFFFFFFF, 0x034262DB, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
                0xFFFFFFFF, 0x03462367, 0x034AC6EB, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x034FCA59, 0x0354727D,
                0x0357C4B8, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x035B140F, 0x036099B5, 0x03664B61,
                0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x036C0829, 0x03700038, 0x0373DEAB, 0xFFFFFFFF, 0xFFFFFFFF,
                0x0377D5A9, 0x037BB82C,
            },
            new uint[] {
                0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x000B643A, 0x0019864A, 0x002450C1, 0x0031DAB1, 0xFFFFFFFF,
                0x00417065, 0x0050B805, 0x00604DB9, 0x006F9559, 0x007EDCF9, 0xFFFFFFFF, 0xFFFFFFFF, 0x0092E08D,
                0xFFFFFFFF, 0xFFFFFFFF, 0x00A209F1, 0xFFFFFFFF, 0xFFFFFFFF, 0x00B3F1DA, 0xFFFFFFFF, 0xFFFFFFFF,
                0x00C31588, 0xFFFFFFFF, 0x00D16C22, 0x00DF82FB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00EFA6C9, 0xFFFFFFFF,
                0xFFFFFFFF, 0x0103EA1B, 0xFFFFFFFF, 0xFFFFFFFF, 0x0115C6F6, 0x0125335C, 0x0133D009, 0x013EAB34,
                0xFFFFFFFF, 0x014BD02F, 0x0154CB50, 0xFFFFFFFF, 0x0166C2D9, 0x0176E14A, 0xFFFFFFFF, 0x018B0753,
                0x019F8C81, 0xFFFFFFFF, 0x01B3E2C8, 0x01C6DF73, 0xFFFFFFFF, 0xFFFFFFFF, 0x01D88C71, 0x01EAB83F,
                0xFFFFFFFF, 0x01F9879D, 0xFFFFFFFF, 0xFFFFFFFF, 0x020A0D54, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
                0xFFFFFFFF, 0x021A8BA0, 0x02275498, 0xFFFFFFFF, 0x0232C871, 0x023E75D4, 0xFFFFFFFF, 0xFFFFFFFF,
                0x02482415, 0xFFFFFFFF, 0xFFFFFFFF, 0x025673D7, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
                0x0266FB98, 0x02794E7F, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x028755D3, 0x02936A82,
                0xFFFFFFFF, 0xFFFFFFFF, 0x02A71E55, 0xFFFFFFFF, 0x02B8F819, 0xFFFFFFFF, 0xFFFFFFFF, 0x02BC71E4,
                0x02CA620F, 0x02D925EB, 0x02E85E22, 0x02FA3394, 0x0300BD87, 0x0314FF53, 0x0323519F, 0x03322772,
                0x03407F39, 0x034D9E9E, 0x0358CDBA, 0x03682AE1, 0x037838C4, 0x03877317, 0x039A2A61, 0x03A5A8AB,
                0x03B1CBB1, 0x03C10E88, 0x03D11B67, 0x03DCE6FE, 0x03ECF368, 0x03FAB735, 0x04074179, 0x0411690A,
                0x041E3298, 0x042D80C9, 0x043834FB, 0x04477B39, 0x0451E0A4, 0x04639C8A, 0x046E2B71, 0x0482939E,
                0x0492BCE7, 0x04A2CC5D, 0x04B2E7E5, 0x04C2ECE4, 0x04D443BD, 0x04E59C49, 0x04F6BEED, 0x05081716,
                0x05147BD7, 0x05217239, 0x052E8C50, 0x053E9A4D, 0x054E56D1, 0x055C7F57, 0x0567DDC8, 0x0579D19D,
                0x05852C08, 0x0593F3C4, 0x05A02342, 0x05AF245C, 0x05BD275F, 0x05CA039C, 0x05D30C85, 0x05DDB5A1,
                0x05E9E3AE, 0x05F4D84D, 0x05FD4496, 0x06064564, 0x0612A7CD, 0x061FDC0E, 0x062FBCD4, 0x063B85A9,
                0x064C3744, 0x065877B1, 0x06657813, 0x0673AADD, 0x0682B1D9, 0x068D5124, 0x0698C275, 0x06A7A19A,
                0x06B24CB4, 0x06C1359D, 0x06D4028F, 0x06E29495, 0x06EDDC3F, 0x06FBDF2E, 0x070C75D5, 0x0718853D,
                0x0723F192, 0x073039D1, 0x073D453B, 
            },
            new uint[] {
                0x00000000, 0xFFFFFFFF, 0x00038D3E, 0x00173FF2, 0x0028715D, 0x00399F0F, 0x004C010B, 0x005E6202,
                0x005F19E5, 0x005FBB5C, 0x006039C3, 0x006148CA, 0x00625655, 0x00636D20, 0x00647F59, 0x00658309,
                0x00666737, 0x0066F4F9, 0x0067709D, 0x0067EC77, 0x0076C0FA, 0x0082CDD1, 0x008E53D0, 0x009A62A6,
                0x00A5EAA2, 0x00C080EE, 0x00C2FAB2, 0x00C57C27, 0x00C80885, 0x00CAAD3B, 0x00CD08E0, 0x00CF8A79,
                0x00D1DAEB, 0x00D461EE, 0x00D6D027, 0x00D918C9, 0x00DB1E05, 0x00DDE981, 0x00DFDE40, 0x00E23895,
                0x00E4967E, 0x00E6C5E0, 0x00E832F5, 0x00EA83EA, 0x00ED088D, 0x00EF4090, 0x00F19F88, 0x00F432AF,
                0x00F60E5A, 0x00FCDEA2, 0x01040CB2, 0x010B2F13, 0x01124ED7, 0x01198006, 0x01210E7A, 0x01289C10,
                0x012FF8C4, 0x0137165F, 0x013EAF7E, 0x01464FB3, 0x014DAFEC, 0x01551340, 0x015CD333, 0x01649395,
                0x016C41F2, 0x0173BFAD, 0x017B741F, 0x01830C76, 0x018AAD44, 0x0192174F, 0x019A849F, 0x01A2F1A7,
                0x01AB4F7B, 0x01AED7A6, 0x01AF0230, 0x01B7E2DD, 
            },
            new uint[] {
                0x00000000, 0x0015FD2E, 0x002F9195, 0x002F91C1, 0x002F91ED, 0x002F9219, 0x002F9245, 0x002F9271,
                0x002F929D, 0x002F92C9, 0x002F92F5, 0x002F9321, 0x002F934D, 0x002F9379, 0x002F93A5, 0x002F93D1,
                0x002F93FD, 0x002F9429, 0x002F9455, 0x002F9481, 0x002F94AD, 0x002F94D9, 0x002F9505, 0x002F9531,
                0x002F955D, 0x002F9589, 0x002F95B5, 0x002F95E1, 0x002F960D, 0x002F9639, 0x002F9665, 0x002F9691,
                0x002F96BD, 0x002F96E9, 0x002F9715, 0x002F9741, 0x002F976D, 0x002F9799, 0x002F97C5, 0x002F97F1,
                0x002F981D, 0x002F9849, 0x002F9875, 0x002F98A1, 0x002F98CD, 0x002F98F9, 0x002F9925, 0x002F9951,
                0x002F997D, 0x002F99A9, 0x002F99D5, 0x002F9A01, 0x002F9A2D, 0x002F9A59, 0x002F9A85, 0x002F9AB1,
                0x002F9ADD, 0x002F9B09, 0x002F9B35, 0x002F9B61, 0x002F9B8D, 0x002F9BB9, 0x002F9BE5, 0x002F9C11,
                0x002F9C3D, 0x002F9C69, 0x002F9C95, 0x002F9CC1, 0x002F9CED, 0x002F9D19, 0x002F9D45, 0x002F9D71,
                0x002F9D9D, 0x002F9DC9, 0x002F9DF5, 0x002F9E21, 0x002F9E4D, 0x002F9E79, 0x002F9EA5, 0x002F9ED1,
                0x002F9EFD, 0x002F9F29, 0x002F9F55, 0x002F9F81, 0x002F9FAD, 0x002F9FD9, 0x002FA005, 0x002FA031,
                0x002FA05D, 0x002FA089, 0x002FA0B5, 0x002FA0E1, 0x002FA10D, 0x002FA139, 0x002FA165, 0x002FA191,
                0x002FA1BD, 0x002FA1E9, 0x002FA215, 0x002FA241, 0x002FA26D, 0x002FA299, 0x002FA2C5, 0x002FA2F1,
                0x002FA31D, 0x002FA349, 0x002FA375, 0x002FA3A1, 0x002FA3CD, 0x002FA3F9, 0x002FA425, 0x002FA451,
                0x002FA47D, 0x002FA4A9, 0x002FA4D5, 0x002FA501, 0x002FA52D, 0x002FA559, 0x002FA585, 0x002FA5B1,
                0x002FA5DD, 0x0037B6B9, 0x004E8A46, 0x00569777, 0x006A87E9, 0x0076E304, 0x007AB1CF, 0x008208CE,
                0x0090E839, 0x0090E865, 0x0090E891, 0x009BE7FD, 0x00A0AD79, 0x00A4BE4D, 0x00A66973, 0x00A9ACDE,
                0x00B3DA78, 0x00BD7A58, 0x00CBA6D9, 0x00D3E2FA, 0x00D63ED7, 0x00D63F03, 0x00F49946, 0x01383B37,
                0x013AA44F, 0x013F6410, 0x0148DF01, 0x014C439A, 0x0151FD75, 0x01552830, 0x0157B8E2, 0x0159359E,
                0x015B5700, 0x015E1053, 0x0161AD83, 0x0162BEB6, 0x0163DBD1, 0x01655DED, 0x016B35A6, 0x0171F69D,
                0x01774F3A, 0x017A9867, 0x017D9BF2, 0x017F66B3, 0x0181407A, 0x018551CB, 0x01881330, 0x018D416D,
                0x0199E132, 0x01A300D4, 0x01A4D2E9, 0x01A56848, 0x01A852CD, 0x01AC5D56, 0x01AE9637, 0x01B3CEA7,
                0x01B8728F, 0x01C15348, 0x01C15374, 0x01C7D6F6, 0x01DC9C4A, 0x01E55586, 0x01F5BA0A, 0x01F84D10,
                0x01F84D3C, 0x01FE84DE, 0x020F9871, 0x020F989D, 0x0234B41C, 0x0234B448, 0x023B6BEB, 0x024F192B,
                0x0267BA98, 0x026A3C83, 0x0271B0F6, 0x0275BDDA, 0x028705D6, 0x0295CF36, 0x02A14CB4, 0x02BBE5C5,
                0x0324C721, 0x032C9879, 0x0333498F, 0x03369807, 0x0339DD87, 0x033E1224, 0x0341EE89, 0x034585D5,
                0x034AB99F, 0x034B6CF2, 0x034C7FBC, 0x034EAA0A, 0x0358340F, 0x03643102, 0x036DBDEE, 0x0374BA90,
                0x03772CB5, 0x037B1AD9, 0x037CF6D3, 0x03841813, 0x038B78C9, 0x03939D08, 0x039974E4, 0x039EE3D2,
                0x03A0AAFA, 0x03A27B07, 0x03A881D9, 0x03A8B4FE, 0x03AB8BCE, 0x03B0843E, 0x03B341E1, 0x03B4F39B,
                0x03C9D84F, 0x03D04D05, 0x03DE0272, 0x03DE029E, 0x03E001DA, 0x03E00206, 0x03E6BE49, 0x03FBF90C,
                0x04090223, 0x0422429D, 0x0426C1A1, 0x042EC389, 0x044F51FB, 0x04751EF5, 0x047C96A0, 0x0486E243,
                0x049A0084, 0x04ABCDE7, 0x04F049FE, 0x04F6FF91, 0x04FC3565, 0x04FEA053, 0x0501DF1A, 0x05041EBE,
                0x05097D09, 0x05097D35, 0x050DFE06, 0x05114AEA, 0x05148A11, 0x051867B1, 0x051B0278, 0x051C6306,
                0x051F96DE, 0x0522A916, 0x0524DC2C, 0x05260080, 0x052911EA, 0x052A7A87, 0x052C755A, 0x052E4616,
                0x05341E3E, 0x053ADC4D, 0x053DDF10, 0x0540CB62, 0x0543CC49, 0x054E9452, 0x055403F3, 0x056043B2,
                0x05718C74, 0x058ADD82, 0x05947791, 0x05A535F4, 0x05BD4DCE, 0x05C2AB4B, 0x05D0D0B5, 0x05D6F75A,
                0x05E699A7, 0x05E7E54F, 0x05E82DF3, 0x06028F34, 0x060804A2, 0x060FF814, 0x06127076, 0x061ACCD5,
                0x0626F9D4, 0x0642697B, 0x064739D4, 0x064E769F, 0x0679AD80, 0x06C155B3, 0x06CE519E, 0x06D10D62,
                0x06D7D9F4, 0x06DAA2D2, 0x06DDB5AF, 0x06E20BC8, 0x06E34F23, 0x06E5ABD2, 0x06E82531, 0x06EC2BCB,
                0x06EC2BF7, 0x06EE6A57, 0x06F1D3CA, 0x06F31BF2, 0x06F58667, 0x06F8FBB2, 0x06FCFD25, 0x0701C1CD,
                0x070501FF, 0x07069ACD, 0x0709B4E9, 0x070DF42F, 0x0710AAD4, 0x07190FF4, 0x071B69D4, 0x0720ED64,
                0x072301BC, 0x072EDA4F, 0x072EDA7B, 0x0737826F, 0x0740F0A7, 0x0749F5D1, 0x074A4EA9, 0x0759F52C,
                0x075BE522, 0x077FFAAB, 0x077FFAD7, 0x079C8843, 0x07A979A4, 0x07A979D0, 0x07B07564, 0x07D1053F,
                0x0800E761, 0x08563C55, 0x0860B67C, 0x0865AAD9, 0x086ABC1C, 0x086AE7D2, 0x086B25EB, 0x086B9910,
                0x086D86A9, 0x086ECFB4, 0x0872C0B8, 0x0875C694, 0x0877D53E, 0x087B9839, 0x087F3212, 0x088378E7,
                0x0885F2F2, 0x08874F0D, 0x0889C6ED, 0x088A6121, 0x089023F2, 0x0891D7BE, 0x0892CA5E, 0x0893EB78,
                0x0897071B, 0x089A048C, 0x08A10739, 0x08AB453C, 0x08AEF93D, 0x08B6D7E6, 0x08BA2D5F, 0x08C3F9EB,
                0x08D2B325, 0x08D36E48, 0x08DD3F27, 0x08F5ACCC, 0x08FB7558, 0x08FB7584, 0x0907BB1D, 0x092B768A,
                0x093DF427, 0x094CB928, 0x09595209, 0x09791D6F, 0x09854694, 0x098BDA92, 0x098BDABE, 0x098BDAEA,
                0x09A49495, 0x09A8BA1E, 0x09B19DB6, 0x09B5CCF3, 0x09BB99C1, 0x09C16D5C, 0x0A028547, 0x0A060985,
                0x0A086FC5, 0x0A0D4C41, 0x0A10ED71, 0x0A138902, 0x0A14C3CE, 0x0A1A447C, 0x0A1F30B8, 0x0A2561F0,
                0x0A273374, 0x0A27D5D8, 0x0A2EF9E0, 0x0A3139AF, 0x0A35F0FF, 0x0A3AF01A, 0x0A3D7378, 0x0A3F64A5,
                0x0A4375A6, 
            },
            new uint[] {
                0x00000000, 0x00002788, 0x00006D9D, 0x00008DFC, 0x0000DD31, 0x00013E16, 0x00017091, 0x00019F53,
                0x0001C1E4, 0x0001E27E, 0x0001FD7D, 0x00021AD0, 0x000253EC, 0x0002ABA7, 0x0002C10E, 0x00030112,
                0x0003110D, 0x000364B7, 0x00037C41, 0x0004160E, 0x00043049, 0x00049719, 0x0004CEB3, 0x0004EA2B,
                0x00056E8B, 0x0005A495, 0x0005C024, 0x00060638, 0x00063439, 0x0007119A, 0x0007D96C, 0x0008C570,
                0x0009549C, 0x000A2C9D, 0x000ADAB3, 0x000B1D32, 0x000B5D62, 0x000B7820, 0x000B8E73, 0x000BA479,
                0xFFFFFFFF, 0x000BB7A7, 0x000BE8B7
            },
            new uint[] {
                0x00000000, 0x0137C018, 0x01F2B034, 0x05F2F048, 0x08507060, 0x0A4EF078, 0x0D2EA290, 0x103C22A4,
                0x127002BC, 0x1527A4F4, 0x174406E8, 0x187886FC
            },
            new uint[] {
                0x00000000, 0x00000D74, 0x00001B0D, 0x00001C2B, 0x00001D93, 0x00001EAF, 0x00001F51, 0x00001FAC,
                0x000020B8, 0x00002215, 0x000022F6, 0x00002427, 0x0000247E, 0x0000258E, 0x00002641, 0x00002744,
                0x00002800, 0x00002850, 0x00002938, 0x00002A2E, 0x00002AA2, 0x00002BA1, 0x00002C0C, 0x00002CD2,
                0x00002E0C, 0x00002EC9, 0x00002F66, 0x00002FDB, 0x000030DA, 0x000031F3, 0x00003302, 0x0000340F,
                0x00003474, 0x00003589, 0x0000362F, 0x000036F1, 0x000037AC, 0x00003834, 0x00003988, 0x00003B1A,
                0x00003B8E, 0x00003C0E, 0x00003CA1, 0x00003D44, 0x00003FE8, 0x00004108, 0x00004203, 0x000042A8,
                0x00004397, 0x0000457D, 0x000046ED, 0x00004827, 0x000048CA, 0x0000497F, 0x00004AA2, 0x00004D31,
                0x00004DA1, 0x00004E3C, 0x00004F64, 0x0000505F, 0x00005129, 0x000053BB, 0x00005431, 0x0000552B,
                0x000057D1, 0x00005979, 0x00005AF6, 0x00005B95, 0x00005D52, 0x00005E2D, 0x00005F06, 0x000060A6,
                0x0000612F, 0x000062D4, 0x00006513, 0x000066EA, 0x000067DD, 0x0000683E, 0x00006962, 0x00006BB0,
                0x00006CE5, 0x00006E0C, 0x00006E6D, 0x00006FA9, 0x000073AB, 0x000075B0, 0x000076DE, 0x0000776C,
                0x000078C7, 0x000079F2, 0x00007AE6, 0x00007BC7, 0x00007C3F, 0x00007E95, 0x00007FE1, 0x00008134,
                0x000082D0, 0x0000834F, 0x000084F7, 0x000086A7, 0x0000888C, 0x00008903, 0x000089DF, 0x00008C29,
                0x00008CE7, 0x00008D4B, 0x00008F10, 0x000091F5, 0x0000924A, 0x000094A2, 0x0000962A, 0x000096BD,
                0x0000983E, 0x00009A52, 0x00009AD8, 0x00009B83, 0x00009CB4, 0x00009D10, 0x00009E3F, 0x00009F36,
                0x0000A01C, 0x0000A6CE, 0x0000B096, 0x0000B558, 0x0000C208, 0x0000C889, 0x0000CC93, 0x0000CFDF,
                0x0000DA4A, 0x0000DFD6, 0x0000E823, 0x0000EC90, 0x0000F695, 0x0000F936, 0x00010576, 0x0001094E,
                0x000112DD, 0x000117DF, 0x00011ED8, 0x0001244E, 0x000128DB, 0x00013081, 0x00014261, 0x00015C1D,
                0x00016374, 0x00016620, 0x00016AD8, 0x00016D64, 0x0001701B, 0x000171F0, 0x00017376, 0x0001743E,
                0x00017869, 0x00017C04, 0x00017F07, 0x0001812C, 0x00018312, 0x00018485, 0x0001872A, 0x00018B7F,
                0x00018E14, 0x0001900D, 0x000191B9, 0x00019317, 0x0001952C, 0x000197C4, 0x00019A57, 0x00019D17,
                0x0001A2D9, 0x0001A6F6, 0x0001A8CD, 0x0001AA33, 0x0001AC54, 0x0001AF58, 0x0001B1E2, 0x0001B530,
                0x0001B788, 0x0001BF50, 0x0001C189, 0x0001C527, 0x0001CFFA, 0x0001D603, 0x0001E27D, 0x0001E510,
                0x0001E99D, 0x0001EEA0, 0x0001F6BA, 0x0001FC97, 0x00020CB2, 0x0002123E, 0x000217C9, 0x000223E7,
                0x00022FD5, 0x0002346B, 0x00023FAB, 0x00024848, 0x0002512C, 0x00025D75, 0x00026622, 0x00026FFB,
                0x0002912C, 0x00029AA1, 0x00029D24, 0x00029EFD, 0x0002A11E, 0x0002A559, 0x0002A85C, 0x0002AB45,
                0x0002AECE, 0x0002B016, 0x0002B1E4, 0x0002B34D, 0x0002B94B, 0x0002BDE9, 0x0002C268, 0x0002C6EC,
                0x0002C8DC, 0x0002CAC9, 0x0002CC97, 0x0002D019, 0x0002D38E, 0x0002D817, 0x0002DC60, 0x0002DF66,
                0x0002E0E6, 0x0002E23D, 0x0002E56A, 0x0002E629, 0x0002E7AE, 0x0002EA58, 0x0002EBE0, 0x0002ED8A,
                0x0002F867, 0x0002FE55, 0x00030541, 0x00030707, 0x00030A82, 0x00030E7E, 0x00031494, 0x00031F9A,
                0x00032541, 0x0003320E, 0x00033A22, 0x00033F13, 0x00034BB8, 0x00035A64, 0x00035FB6, 0x00036523,
                0x00036FD4, 0x00037BBD, 0x000394E8, 0x00039A76, 0x00039D2E, 0x00039E11, 0x0003A017, 0x0003A31B,
                0x0003A552, 0x0003A7F0, 0x0003AA7D, 0x0003ACBD, 0x0003AFC2, 0x0003B271, 0x0003B5C2, 0x0003B782,
                0x0003BA6E, 0x0003BD65, 0x0003BF0C, 0x0003C073, 0x0003C2F1, 0x0003C4B2, 0x0003C687, 0x0003C7C1,
                0x0003CACC, 0x0003CDD8, 0x0003D06D, 0x0003D1D0, 0x0003D39A, 0x0003DA7C, 0x0003DD1E, 0x0003E48C,
                0x0003EBA6, 0x0003F7AF, 0x0003FDA4, 0x000404A8, 0x00040DD6, 0x00041055, 0x0004161C, 0x00041894,
                0x0004225C, 0x00042375, 0x00042862, 0x0004372B, 0x00043A1F, 0x00043F07, 0x00044556, 0x0004485E,
                0x00044C35, 0x00045ACA, 0x00045DB2, 0x0004611D, 0x00046FF8, 0x000488EE, 0x0004942D, 0x0004965C,
                0x0004991F, 0x00049BD4, 0x00049F0B, 0x0004A141, 0x0004A25B, 0x0004A37F, 0x0004A49A, 0x0004A709,
                0x0004A846, 0x0004A9C2, 0x0004ACA6, 0x0004AE11, 0x0004AF7F, 0x0004B160, 0x0004B366, 0x0004B6BE,
                0x0004B8D0, 0x0004B9E2, 0x0004BBEE, 0x0004BEDF, 0x0004C24A, 0x0004C663, 0x0004CA4E, 0x0004CE26,
                0x0004D0E7, 0x0004D6CA, 0x0004D87C, 0x0004DE91, 0x0004E33C, 0x0004E946, 0x0004EC3B, 0x0004F4E6,
                0x0004F6DD, 0x00050878, 0x000509EC, 0x0005158C, 0x00051CE5, 0x00051E4E, 0x000520E9, 0x00052B85,
                0x00053D39, 0x00055A0E, 0x0005605A, 0x00056335, 0x0005651C, 0x00056590, 0x0005665F, 0x000566F9,
                0x000569AB, 0x00056B69, 0x00056E96, 0x00057149, 0x000572C4, 0x000574D3, 0x00057740, 0x00057AEB,
                0x00057CD3, 0x00057D9A, 0x00057EEE, 0x0005805A, 0x0005834E, 0x00058490, 0x0005854E, 0x0005867F,
                0x0005888E, 0x00058B86, 0x000590D0, 0x00059779, 0x00059BF7, 0x0005A0B3, 0x0005A50F, 0x0005AE3A,
                0x0005B4EE, 0x0005B8BE, 0x0005BCC5, 0x0005C780, 0x0005CAF1, 0x0005D3F7, 0x0005D8D8, 0x0005E5FF,
                0x0005EC8F, 0x0005F1AA, 0x0005F6D2, 0x00060519, 0x00060C43, 0x00060FEF, 0x00061362, 0x00061575,
                0x00061EC7, 0x00062178, 0x0006266E, 0x00062ACB, 0x00063054, 0x000632AC, 0x000647C4, 0x00064AD4,
                0x00064CEA, 0x00064F3C, 0x0006512B, 0x000652A7, 0x0006556D, 0x0006587A, 0x00065B8B, 0x00065E17,
                0x00065FCC, 0x00066321, 0x00066694, 0x00066952, 0x00066BA7, 0x00066E9B, 0x00067074, 0x000671A1,
                0x000673ED, 0x00068EEE, 
            },
            new uint[] {
                0x00000000, 0x0004581C, 0x00048652, 0x0005906C, 0x00074888
            },
        };
    }

    [Serializable]
    public class CmbScheme : ResourceScheme
    {
        public IDictionary<string, uint[][]>   KnownSchemes;
    }
}
